// 水墨风格视觉效果系统

import { Position } from '../types/game';

// 粒子类型
export type ParticleType = 'ink' | 'smoke' | 'sparkle' | 'leaf' | 'water' | 'fire' | 'wind';

// 粒子接口
export interface Particle {
  id: string;
  type: ParticleType;
  position: Position;
  velocity: { x: number; y: number };
  size: number;
  opacity: number;
  color: string;
  life: number;
  maxLife: number;
  rotation: number;
  rotationSpeed: number;
  scale: number;
  scaleSpeed: number;
}

// 动画效果接口
export interface AnimationEffect {
  id: string;
  type: string;
  position: Position;
  startTime: number;
  duration: number;
  progress: number;
  properties: Record<string, any>;
  onUpdate?: (effect: AnimationEffect, progress: number) => void;
  onComplete?: (effect: AnimationEffect) => void;
}

// 粒子配置
interface ParticleConfig {
  color: string[];
  size: { min: number; max: number };
  life: { min: number; max: number };
  velocity: { min: number; max: number };
  opacity: { start: number; end: number };
  scale: { start: number; end: number };
}

// 粒子配置数据
const PARTICLE_CONFIGS: Record<ParticleType, ParticleConfig> = {
  ink: {
    color: ['#1f2937', '#374151', '#4b5563'],
    size: { min: 2, max: 8 },
    life: { min: 1000, max: 3000 },
    velocity: { min: 10, max: 30 },
    opacity: { start: 0.8, end: 0 },
    scale: { start: 1, end: 2 }
  },
  smoke: {
    color: ['#f3f4f6', '#e5e7eb', '#d1d5db'],
    size: { min: 4, max: 12 },
    life: { min: 2000, max: 4000 },
    velocity: { min: 5, max: 15 },
    opacity: { start: 0.6, end: 0 },
    scale: { start: 0.5, end: 1.5 }
  },
  sparkle: {
    color: ['#fbbf24', '#f59e0b', '#d97706'],
    size: { min: 1, max: 4 },
    life: { min: 500, max: 1500 },
    velocity: { min: 20, max: 50 },
    opacity: { start: 1, end: 0 },
    scale: { start: 1, end: 0.2 }
  },
  leaf: {
    color: ['#10b981', '#059669', '#047857'],
    size: { min: 3, max: 6 },
    life: { min: 3000, max: 5000 },
    velocity: { min: 8, max: 20 },
    opacity: { start: 0.9, end: 0.1 },
    scale: { start: 1, end: 0.8 }
  },
  water: {
    color: ['#3b82f6', '#2563eb', '#1d4ed8'],
    size: { min: 2, max: 5 },
    life: { min: 1500, max: 2500 },
    velocity: { min: 15, max: 35 },
    opacity: { start: 0.7, end: 0 },
    scale: { start: 1, end: 1.2 }
  },
  fire: {
    color: ['#ef4444', '#dc2626', '#b91c1c'],
    size: { min: 3, max: 8 },
    life: { min: 800, max: 1800 },
    velocity: { min: 10, max: 25 },
    opacity: { start: 0.9, end: 0 },
    scale: { start: 0.8, end: 1.5 }
  },
  wind: {
    color: ['#e5e7eb', '#d1d5db', '#9ca3af'],
    size: { min: 1, max: 3 },
    life: { min: 2000, max: 4000 },
    velocity: { min: 30, max: 60 },
    opacity: { start: 0.4, end: 0 },
    scale: { start: 1, end: 0.5 }
  }
};

// 视觉效果系统类
export class VisualEffectsSystem {
  private particles: Particle[] = [];
  private animations: AnimationEffect[] = [];
  private canvas: HTMLCanvasElement | null = null;
  private ctx: CanvasRenderingContext2D | null = null;
  private lastUpdateTime: number = 0;
  private isPaused: boolean = false;
  private maxParticles: number = 500;

  constructor(canvas?: HTMLCanvasElement) {
    if (canvas) {
      this.setCanvas(canvas);
    }
    this.lastUpdateTime = Date.now();
  }

  // 设置画布
  setCanvas(canvas: HTMLCanvasElement): void {
    this.canvas = canvas;
    this.ctx = canvas.getContext('2d');
  }

  // 更新系统
  update(deltaTime: number): void {
    if (this.isPaused) return;

    const currentTime = Date.now();
    const actualDeltaTime = currentTime - this.lastUpdateTime;
    this.lastUpdateTime = currentTime;

    // 更新粒子
    this.updateParticles(actualDeltaTime / 1000);

    // 更新动画
    this.updateAnimations(currentTime);

    // 渲染效果
    if (this.ctx) {
      this.render();
    }
  }

  // 更新粒子
  private updateParticles(deltaSeconds: number): void {
    this.particles = this.particles.filter(particle => {
      // 更新位置
      particle.position.x += particle.velocity.x * deltaSeconds;
      particle.position.y += particle.velocity.y * deltaSeconds;

      // 更新生命周期
      particle.life -= deltaSeconds * 1000;
      const lifeProgress = 1 - (particle.life / particle.maxLife);

      // 更新属性
      const config = PARTICLE_CONFIGS[particle.type];
      particle.opacity = this.lerp(config.opacity.start, config.opacity.end, lifeProgress);
      particle.scale = this.lerp(config.scale.start, config.scale.end, lifeProgress);
      particle.rotation += particle.rotationSpeed * deltaSeconds;

      // 应用重力和阻力
      particle.velocity.y += 20 * deltaSeconds; // 重力
      particle.velocity.x *= 0.98; // 阻力
      particle.velocity.y *= 0.98;

      return particle.life > 0;
    });
  }

  // 更新动画
  private updateAnimations(currentTime: number): void {
    this.animations = this.animations.filter(animation => {
      const elapsed = currentTime - animation.startTime;
      animation.progress = Math.min(1, elapsed / animation.duration);

      // 更新动画
      if (animation.onUpdate) {
        animation.onUpdate(animation, animation.progress);
      }

      // 检查是否完成
      if (animation.progress >= 1) {
        if (animation.onComplete) {
          animation.onComplete(animation);
        }
        return false;
      }

      return true;
    });
  }

  // 渲染效果
  private render(): void {
    if (!this.ctx || !this.canvas) return;

    // 清除画布（使用水墨风格的背景）
    this.ctx.globalCompositeOperation = 'source-over';
    
    // 渲染粒子
    this.particles.forEach(particle => {
      this.renderParticle(particle);
    });

    // 渲染动画效果
    this.animations.forEach(animation => {
      this.renderAnimation(animation);
    });
  }

  // 渲染粒子
  private renderParticle(particle: Particle): void {
    if (!this.ctx) return;

    this.ctx.save();
    
    // 设置透明度
    this.ctx.globalAlpha = Math.max(0, particle.opacity);
    
    // 移动到粒子位置
    this.ctx.translate(particle.position.x, particle.position.y);
    this.ctx.rotate(particle.rotation);
    this.ctx.scale(particle.scale, particle.scale);
    
    // 根据粒子类型渲染
    switch (particle.type) {
      case 'ink':
        this.renderInkParticle(particle);
        break;
      case 'smoke':
        this.renderSmokeParticle(particle);
        break;
      case 'sparkle':
        this.renderSparkleParticle(particle);
        break;
      case 'leaf':
        this.renderLeafParticle(particle);
        break;
      case 'water':
        this.renderWaterParticle(particle);
        break;
      case 'fire':
        this.renderFireParticle(particle);
        break;
      case 'wind':
        this.renderWindParticle(particle);
        break;
    }
    
    this.ctx.restore();
  }

  // 渲染水墨粒子
  private renderInkParticle(particle: Particle): void {
    if (!this.ctx) return;

    const gradient = this.ctx.createRadialGradient(0, 0, 0, 0, 0, particle.size);
    gradient.addColorStop(0, particle.color + 'ff');
    gradient.addColorStop(0.7, particle.color + '80');
    gradient.addColorStop(1, particle.color + '00');
    
    this.ctx.fillStyle = gradient;
    this.ctx.beginPath();
    this.ctx.arc(0, 0, particle.size, 0, Math.PI * 2);
    this.ctx.fill();
  }

  // 渲染烟雾粒子
  private renderSmokeParticle(particle: Particle): void {
    if (!this.ctx) return;

    const gradient = this.ctx.createRadialGradient(0, 0, 0, 0, 0, particle.size);
    gradient.addColorStop(0, particle.color + '60');
    gradient.addColorStop(1, particle.color + '00');
    
    this.ctx.fillStyle = gradient;
    this.ctx.beginPath();
    this.ctx.arc(0, 0, particle.size, 0, Math.PI * 2);
    this.ctx.fill();
  }

  // 渲染闪光粒子
  private renderSparkleParticle(particle: Particle): void {
    if (!this.ctx) return;

    this.ctx.fillStyle = particle.color;
    this.ctx.beginPath();
    this.ctx.moveTo(0, -particle.size);
    this.ctx.lineTo(particle.size * 0.3, 0);
    this.ctx.lineTo(0, particle.size);
    this.ctx.lineTo(-particle.size * 0.3, 0);
    this.ctx.closePath();
    this.ctx.fill();
    
    // 添加十字光芒
    this.ctx.strokeStyle = particle.color;
    this.ctx.lineWidth = 1;
    this.ctx.beginPath();
    this.ctx.moveTo(-particle.size, 0);
    this.ctx.lineTo(particle.size, 0);
    this.ctx.moveTo(0, -particle.size);
    this.ctx.lineTo(0, particle.size);
    this.ctx.stroke();
  }

  // 渲染叶子粒子
  private renderLeafParticle(particle: Particle): void {
    if (!this.ctx) return;

    this.ctx.fillStyle = particle.color;
    this.ctx.beginPath();
    this.ctx.ellipse(0, 0, particle.size * 0.6, particle.size, 0, 0, Math.PI * 2);
    this.ctx.fill();
    
    // 添加叶脉
    this.ctx.strokeStyle = particle.color;
    this.ctx.lineWidth = 0.5;
    this.ctx.beginPath();
    this.ctx.moveTo(0, -particle.size);
    this.ctx.lineTo(0, particle.size);
    this.ctx.stroke();
  }

  // 渲染水滴粒子
  private renderWaterParticle(particle: Particle): void {
    if (!this.ctx) return;

    const gradient = this.ctx.createRadialGradient(
      -particle.size * 0.3, -particle.size * 0.3, 0,
      0, 0, particle.size
    );
    gradient.addColorStop(0, '#ffffff80');
    gradient.addColorStop(0.3, particle.color + 'cc');
    gradient.addColorStop(1, particle.color + '40');
    
    this.ctx.fillStyle = gradient;
    this.ctx.beginPath();
    this.ctx.arc(0, 0, particle.size, 0, Math.PI * 2);
    this.ctx.fill();
  }

  // 渲染火焰粒子
  private renderFireParticle(particle: Particle): void {
    if (!this.ctx) return;

    const gradient = this.ctx.createRadialGradient(0, particle.size * 0.5, 0, 0, 0, particle.size);
    gradient.addColorStop(0, '#fbbf24');
    gradient.addColorStop(0.5, particle.color);
    gradient.addColorStop(1, particle.color + '00');
    
    this.ctx.fillStyle = gradient;
    this.ctx.beginPath();
    this.ctx.moveTo(0, -particle.size);
    this.ctx.quadraticCurveTo(particle.size * 0.5, -particle.size * 0.5, particle.size * 0.3, 0);
    this.ctx.quadraticCurveTo(0, particle.size * 0.8, -particle.size * 0.3, 0);
    this.ctx.quadraticCurveTo(-particle.size * 0.5, -particle.size * 0.5, 0, -particle.size);
    this.ctx.fill();
  }

  // 渲染风粒子
  private renderWindParticle(particle: Particle): void {
    if (!this.ctx) return;

    this.ctx.strokeStyle = particle.color;
    this.ctx.lineWidth = particle.size;
    this.ctx.lineCap = 'round';
    this.ctx.beginPath();
    this.ctx.moveTo(-particle.size * 2, 0);
    this.ctx.lineTo(particle.size * 2, 0);
    this.ctx.stroke();
  }

  // 渲染动画效果
  private renderAnimation(animation: AnimationEffect): void {
    if (!this.ctx) return;

    switch (animation.type) {
      case 'ripple':
        this.renderRippleAnimation(animation);
        break;
      case 'explosion':
        this.renderExplosionAnimation(animation);
        break;
      case 'heal':
        this.renderHealAnimation(animation);
        break;
      case 'buff':
        this.renderBuffAnimation(animation);
        break;
    }
  }

  // 渲染涟漪动画
  private renderRippleAnimation(animation: AnimationEffect): void {
    if (!this.ctx) return;

    const radius = animation.properties.maxRadius * animation.progress;
    const opacity = 1 - animation.progress;
    
    this.ctx.save();
    this.ctx.globalAlpha = opacity;
    this.ctx.strokeStyle = animation.properties.color || '#3b82f6';
    this.ctx.lineWidth = 2;
    this.ctx.beginPath();
    this.ctx.arc(animation.position.x, animation.position.y, radius, 0, Math.PI * 2);
    this.ctx.stroke();
    this.ctx.restore();
  }

  // 渲染爆炸动画
  private renderExplosionAnimation(animation: AnimationEffect): void {
    if (!this.ctx) return;

    const radius = animation.properties.maxRadius * animation.progress;
    const opacity = 1 - animation.progress;
    
    this.ctx.save();
    this.ctx.globalAlpha = opacity;
    
    const gradient = this.ctx.createRadialGradient(
      animation.position.x, animation.position.y, 0,
      animation.position.x, animation.position.y, radius
    );
    gradient.addColorStop(0, animation.properties.color + 'ff');
    gradient.addColorStop(0.7, animation.properties.color + '80');
    gradient.addColorStop(1, animation.properties.color + '00');
    
    this.ctx.fillStyle = gradient;
    this.ctx.beginPath();
    this.ctx.arc(animation.position.x, animation.position.y, radius, 0, Math.PI * 2);
    this.ctx.fill();
    this.ctx.restore();
  }

  // 渲染治疗动画
  private renderHealAnimation(animation: AnimationEffect): void {
    if (!this.ctx) return;

    const y = animation.position.y - 30 * animation.progress;
    const opacity = 1 - animation.progress;
    
    this.ctx.save();
    this.ctx.globalAlpha = opacity;
    this.ctx.fillStyle = '#10b981';
    this.ctx.font = '16px Arial';
    this.ctx.textAlign = 'center';
    this.ctx.fillText(`+${animation.properties.amount}`, animation.position.x, y);
    this.ctx.restore();
  }

  // 渲染增益动画
  private renderBuffAnimation(animation: AnimationEffect): void {
    if (!this.ctx) return;

    const scale = 1 + Math.sin(animation.progress * Math.PI * 4) * 0.1;
    const opacity = 1 - animation.progress;
    
    this.ctx.save();
    this.ctx.globalAlpha = opacity;
    this.ctx.translate(animation.position.x, animation.position.y);
    this.ctx.scale(scale, scale);
    
    this.ctx.strokeStyle = animation.properties.color || '#fbbf24';
    this.ctx.lineWidth = 2;
    this.ctx.beginPath();
    this.ctx.arc(0, 0, 20, 0, Math.PI * 2);
    this.ctx.stroke();
    
    this.ctx.restore();
  }

  // 创建粒子效果
  createParticleEffect(
    type: ParticleType,
    position: Position,
    count: number = 10,
    options: Partial<{
      spread: number;
      force: number;
      color: string;
      size: number;
    }> = {}
  ): void {
    if (this.particles.length + count > this.maxParticles) {
      // 移除最老的粒子
      this.particles.splice(0, count);
    }

    const config = PARTICLE_CONFIGS[type];
    const spread = options.spread || 360;
    const force = options.force || 1;

    for (let i = 0; i < count; i++) {
      const angle = (spread / count) * i + Math.random() * (spread / count);
      const velocity = this.lerp(config.velocity.min, config.velocity.max, Math.random()) * force;
      const life = this.lerp(config.life.min, config.life.max, Math.random());
      
      const particle: Particle = {
        id: this.generateId(),
        type,
        position: { x: position.x, y: position.y },
        velocity: {
          x: Math.cos(angle * Math.PI / 180) * velocity,
          y: Math.sin(angle * Math.PI / 180) * velocity
        },
        size: options.size || this.lerp(config.size.min, config.size.max, Math.random()),
        opacity: config.opacity.start,
        color: options.color || config.color[Math.floor(Math.random() * config.color.length)],
        life,
        maxLife: life,
        rotation: Math.random() * Math.PI * 2,
        rotationSpeed: (Math.random() - 0.5) * 4,
        scale: config.scale.start,
        scaleSpeed: 0
      };
      
      this.particles.push(particle);
    }
  }

  // 创建动画效果
  createAnimation(
    type: string,
    position: Position,
    duration: number,
    properties: Record<string, any> = {},
    callbacks: {
      onUpdate?: (effect: AnimationEffect, progress: number) => void;
      onComplete?: (effect: AnimationEffect) => void;
    } = {}
  ): string {
    const animation: AnimationEffect = {
      id: this.generateId(),
      type,
      position: { x: position.x, y: position.y },
      startTime: Date.now(),
      duration,
      progress: 0,
      properties,
      onUpdate: callbacks.onUpdate,
      onComplete: callbacks.onComplete
    };
    
    this.animations.push(animation);
    return animation.id;
  }

  // 创建预设效果
  createUnitDeployEffect(position: Position): void {
    this.createParticleEffect('ink', position, 15, { spread: 360, force: 0.5 });
    this.createAnimation('ripple', position, 800, {
      maxRadius: 30,
      color: '#3b82f6'
    });
  }

  createEnemyDeathEffect(position: Position): void {
    this.createParticleEffect('smoke', position, 20, { spread: 180, force: 0.8 });
    this.createParticleEffect('sparkle', position, 8, { spread: 360, force: 1.2 });
  }

  createSkillEffect(position: Position, skillType: string): void {
    switch (skillType) {
      case 'fireAttack':
        this.createParticleEffect('fire', position, 25, { spread: 360, force: 1.5 });
        this.createAnimation('explosion', position, 1000, {
          maxRadius: 50,
          color: '#ef4444'
        });
        break;
      case 'reinforcement':
        this.createParticleEffect('sparkle', position, 15, { spread: 360, force: 1 });
        this.createAnimation('buff', position, 2000, {
          color: '#3b82f6'
        });
        break;
      case 'inspire':
        this.createParticleEffect('sparkle', position, 30, { spread: 360, force: 2 });
        break;
    }
  }

  createMoodCollectEffect(position: Position, moodType: string): void {
    const colors = {
      moon: '#e5e7eb',
      wind: '#10b981',
      bamboo: '#059669',
      lotus: '#ec4899',
      crane: '#f59e0b',
      mountain: '#6366f1'
    };
    
    const color = colors[moodType as keyof typeof colors] || '#3b82f6';
    
    this.createParticleEffect('sparkle', position, 12, {
      spread: 360,
      force: 1.5,
      color
    });
    
    this.createAnimation('ripple', position, 600, {
      maxRadius: 25,
      color
    });
  }

  // 暂停/恢复系统
  setPaused(paused: boolean): void {
    this.isPaused = paused;
    if (!paused) {
      this.lastUpdateTime = Date.now();
    }
  }

  // 清理系统
  cleanup(): void {
    this.particles = [];
    this.animations = [];
  }

  // 设置最大粒子数
  setMaxParticles(max: number): void {
    this.maxParticles = Math.max(50, Math.min(1000, max));
  }

  // 获取系统状态
  getStatus(): {
    particleCount: number;
    animationCount: number;
    isPaused: boolean;
  } {
    return {
      particleCount: this.particles.length,
      animationCount: this.animations.length,
      isPaused: this.isPaused
    };
  }

  // 工具方法
  private lerp(start: number, end: number, t: number): number {
    return start + (end - start) * t;
  }

  private generateId(): string {
    return Math.random().toString(36).substr(2, 9);
  }
}